package com.mikepenz.fastadapter.app.items

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.IItemVHFactory
import com.mikepenz.fastadapter.IItemViewGenerator
import com.mikepenz.fastadapter.app.R
import com.mikepenz.fastadapter.items.AbstractItem
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass

@RealmClass
open class RealmSampleUserItem : RealmObject(), IItem<RealmSampleUserItem.ViewHolder>, IItemVHFactory<RealmSampleUserItem.ViewHolder>, IItemViewGenerator {

    // Standard getters & setters generated by your IDE…
    var name: String? = null
        private set

    // the identifier for this item
    @PrimaryKey
    override var identifier: Long = -1L

    // the tag for this item
    /**
     * @return the tag of this item
     */
    /**
     * set the tag of this item
     *
     * @param object
     * @return this
     */
    @Ignore
    override var tag: Any? = null

    @Ignore
    override val factory: IItemVHFactory<ViewHolder>? = null

    // defines if this item is enabled
    @Ignore
    override var isEnabled = true

    // defines if the item is selected
    @Ignore
    override var isSelected = false

    // defines if this item is selectable
    @Ignore
    override var isSelectable = true

    /**
     * returns the type of the Item. Can be a hardcoded INT, but preferred is a defined id
     */
    override val type: Int
        get() = R.id.fastadapter_realm_sample_user_item_id

    /**
     * returns the layout for the given item
     */
    val layoutRes: Int
        get() = R.layout.letter_item

    /**
     * set the name of this item
     */
    fun withName(name: String): RealmSampleUserItem {
        this.name = name
        return this
    }

    /**
     * set the identifier of this item
     */
    fun withIdentifier(identifier: Long): RealmSampleUserItem {
        this.identifier = identifier
        return this
    }

    /**
     * generates a view by the defined LayoutRes
     */
    override fun generateView(ctx: Context): View {
        val viewHolder = getViewHolder(LayoutInflater.from(ctx).inflate(layoutRes, null, false))

        //as we already know the type of our ViewHolder cast it to our type
        bindView(viewHolder, ArrayList())

        //return the bound view
        return viewHolder.itemView
    }

    /**
     * generates a view by the defined LayoutRes and pass the LayoutParams from the parent
     *
     * @param ctx
     * @param parent
     * @return
     */
    override fun generateView(ctx: Context, parent: ViewGroup): View {
        val viewHolder = getViewHolder(LayoutInflater.from(ctx).inflate(layoutRes, parent, false))

        //as we already know the type of our ViewHolder cast it to our type
        bindView(viewHolder, ArrayList())
        //return the bound and generatedView
        return viewHolder.itemView
    }

    /**
     * Generates a ViewHolder from this Item with the given parent
     *
     * @param parent
     * @return
     */
    override fun getViewHolder(parent: ViewGroup): ViewHolder {
        return getViewHolder(LayoutInflater.from(parent.context).inflate(layoutRes, parent, false))
    }

    /**
     * This method returns the ViewHolder for our item, using the provided View.
     *
     * @param v
     * @return the ViewHolder for this Item
     */
    private fun getViewHolder(v: View): ViewHolder {
        return ViewHolder(v)
    }

    /**
     * Binds the data of this item to the given holder
     *
     * @param holder
     */
    override fun bindView(holder: ViewHolder, payloads: List<Any>) {
        //set the selected state of this item. force this otherwise it may is missed when implementing an item
        holder.itemView.isSelected = isSelected

        //set the name
        holder.name.text = name
    }

    override fun unbindView(holder: ViewHolder) {
        holder.name.text = null
    }

    override fun attachToWindow(holder: ViewHolder) {}

    override fun detachFromWindow(holder: ViewHolder) {}

    override fun failedToRecycle(holder: ViewHolder): Boolean {
        return false
    }

    /**
     * If this item equals to the given identifier
     *
     * @param id identifier
     * @return true if identifier equals id, false otherwise
     */
    override fun equals(id: Int): Boolean {
        return id.toLong() == identifier
    }

    /**
     * If this item equals to the given object
     *
     * @param other
     * @return
     */
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other == null || javaClass != other.javaClass) return false
        val that = other as AbstractItem<*>?
        return identifier == that?.identifier
    }

    /**
     * the hashCode implementation
     *
     * @return
     */
    override fun hashCode(): Int = identifier.hashCode()

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var name: TextView = view.findViewById<View>(R.id.text) as TextView
    }
}